package com.towerdefense;

import java.io.*;
import android.content.res.AssetManager;
import android.util.Log;



enum Direction{DIR_UP,DIR_BOTTOM,DIR_LEFT,DIR_RIGHT,DONT_KNOW};
enum Field{FREE,BLOCK,RAFINERY,MINE};

public class Map{
	
	private int fields_x;
	private int fields_y;
	private int start_x;
	private int end_x;
	private int start_y;
	private int end_y;
	private String MapName;
	private String Background="mapa1.png";
	private char[][] CanMove; 
	private int[][] Distance; 
	private char[][] Buildings;
	
	
	public int get_fields_x(){return fields_x;}
	public int get_fields_y(){return fields_y;}
	public String get_map_name(){return MapName;}
	public String get_BackgroundName(){return Background;}
	public MPoint get_StartCoordinates(){
		MPoint point = new MPoint();
		point.x=start_x;
		point.y=start_y;
		return point;
	}
	public MPoint get_EndCoordinates(){
		MPoint point = new MPoint();
		point.x=end_x;
		point.y=end_y;
		return point;
	}
	
	public boolean CanAlienMove(int y,int x)
	{
		if(CanMove[y][x]=='o' && Buildings[y][x]=='o')return true;
		return false;
	}
	public boolean CanBuildTower(int y,int x)
	{
		if(CanMove[y][x]=='o' && Buildings[y][x]=='o')return true;
		return false;
	}
	
	@SuppressWarnings("unused")
	private void CalculateDistance()
	{
		for(int i=0;i<fields_y;i++)
		{
			for(int j=0;j<fields_x;j++)
			{
				Distance[i][j]=999;
			}
		}
		
		Distance[end_y][end_x]=0;
		CalculateDistanceForField(end_y-1,end_x,1);
		CalculateDistanceForField(end_y+1,end_x,1);
		CalculateDistanceForField(end_y,end_x-1,1);
		CalculateDistanceForField(end_y,end_x+1,1);
	}
	private boolean CanMoveHere(int x,int y)
	{
		if(CanMove[y][x]!='o')
			return false;
		if(Buildings[y][x]!='o')
			return false;
		return true;
	}
	private void CalculateDistanceForField(int y,int x,int distance)
	{
		if(x < 0 || y < 0 || x >= fields_x || y >= fields_y)
			return;
		if(GetDistance(x,y)>=distance)return;
		if(CanMoveHere(x,y))
			Distance[y][x]=distance;
		else
			Distance[y][x]=999;
		CalculateDistanceForField(y-1,x,distance+1);
		CalculateDistanceForField(y+1,x,distance+1);
		CalculateDistanceForField(y,x-1,distance+1);
		CalculateDistanceForField(y,x+1,distance+1);
	}
	
	
	@SuppressWarnings("unused")
	private void MapAnalyze()
	{
		for(int i=0;i<fields_y;i++)
		{
			for(int j=0;j<fields_x;j++)
			{
				Buildings[i][j]='o';
				if(CanMove[i][j]=='A')
				{
					start_x=j;
					start_y=i;
				}else if(CanMove[i][j]=='B')
				{
					end_x=i;
					end_y=j;
				}
			}
		
		}
	}
	
	private int GetDistance(int x,int y)
	{
		if(x<0 || y<0 || x>=fields_x || y>=fields_y)
			return 99;
		return Distance[y][x];
	}
	public Direction WhereShouldIGo(MPoint WhereIAm)
	{
		@SuppressWarnings("unused")
		int CurrentDistance=Distance[WhereIAm.y][WhereIAm.x];
		int[] NeighbourDistances = new int[4];
		NeighbourDistances[0]=GetDistance(WhereIAm.y-1,WhereIAm.x);
		NeighbourDistances[1]=GetDistance(WhereIAm.y+1,WhereIAm.x);
		NeighbourDistances[2]=GetDistance(WhereIAm.y,WhereIAm.x-1);
		NeighbourDistances[3]=GetDistance(WhereIAm.y,WhereIAm.x+1);
		int CurrentBest=0;
		for(int i=1;i<4;i++)
		{
			if(NeighbourDistances[i]<NeighbourDistances[i])
				CurrentBest=i;
			if(NeighbourDistances[i]==NeighbourDistances[i])
			{
				
			}
		}
		if(NeighbourDistances[CurrentBest]==999)
			return Direction.DONT_KNOW;
		switch(CurrentBest)
		{
		case 0:
			return Direction.DIR_UP;
		case 1:
			return Direction.DIR_BOTTOM;
		case 2:
			return Direction.DIR_LEFT;
		case 3:
			return Direction.DIR_RIGHT;
		}
		return Direction.DONT_KNOW;
	}
	public void CreateBuilding(int x,int y,char type)
	{
		Buildings[y][x]=type;
	}
	public void DestroyBuilding(int x,int y)
	{
		Buildings[y][x]='o';
	}
	
	public boolean ReadMap(String path,AssetManager am)
	{
		try{
			Log.e("AndEngine", "0");
			String []tmp = am.list("/");
			for(int i=0;i<tmp.length;i++)
				Log.e("AndEngine", "000000000"+tmp[i]);	
			Log.e("AndEngine", "9");
			InputStream is = am.open("map1.txt"); //
			Log.e("AndEngine", "0.5");
            int size = is.available();
            Log.e("AndEngine", "1");
            // Read the entire asset into a local byte buffer.
            byte[] buffer = new byte[size];
            is.read(buffer);
            Log.e("AndEngine", "2");
            is.close();
            Log.e("AndEngine", "3");
            // Convert the buffer into a string.
            String text = new String(buffer);
            Log.e("AndEngine", text);
			int tryb=0;
			int LineNo=0;
			String []lines = text.split("\n");
			int i=0;
			while (i<lines.length)   {
			  String strLine=lines[i++]; 	
			  Log.e("AndEngine", "line : "+strLine);
			  if(strLine=="[META]")
				  {
					  tryb=1;
					  continue;
				  }else if(strLine=="[/META]")
				  {
					  CanMove = new char[fields_y][fields_x];
					  Distance = new int[fields_y][fields_x];
					  Buildings = new char[fields_y][fields_x];
				  }else if(strLine=="[ALIEN_MOVE]")
				  {
					  LineNo=0;
					  tryb=2;
					  continue;
				  }else if(strLine=="[BUILDINGS]")
				  {
					  tryb=3;
					  continue;
				  }else if(strLine.contains("[/"))
				  {
					  tryb=0;
					  continue;
				  }
				  switch(tryb)
				  {
				  case 1:
					  if(strLine.contains("="))
					  {
						  String[]val=strLine.split("=");
						  if(val.length!=2)
						  {
							  continue;
						  }
						  String field=val[0];
						  String value=val[1];
						  if(field=="name")
							  MapName=value;
						  if(field=="map_height")
							  fields_y=Integer.parseInt(value);
						  if(field=="map_width")
							  fields_x=Integer.parseInt(value);
						  if(field=="background")
							  Background=value;
						 
					  }
					  break;
				  case 2:
					  char []str=strLine.toCharArray();
					  for(int j=0;j<fields_x;j++)
					  {
						  
							  CanMove[LineNo][i]=str[i];
					  }
					  LineNo++;
					  
					  break;
				  default:
					break;
				
				  
				  }
			}//end while
			  
			  is.close();
	    }catch (Exception e){
	    	Log.e("AndEngine", "Error: " + e.getMessage());
	    	return false;
	    }
			   
		
		//MapAnalyze();
		//CalculateDistance();	
		return true;
	}
	
}
